package com.koron.device.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.koron.bean.base.Response;
import com.koron.bean.query.OrderItem;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.interceptor.OrderByInterceptor;
import com.koron.common.core.util.CodeTools;
import com.koron.device.bean.*;
import com.koron.device.mapper.EquipmentBackupMapper;
import com.koron.device.mapper.EquipmentMapper;
import com.koron.device.service.EquipmentBackupService;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @anthor chenyiwei
 * @date 2022/4/1
 */
@Service
@Slf4j
public class EquipmentBackupServiceImpl implements EquipmentBackupService {
    @Autowired
    EquipmentBackupMapper mapper;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    @Override
    @TaskAnnotation("getById")
    public Response getById(SessionFactory factory, String id) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        List<EquipmentBackup> equipmentBackup = mapper.getById(id);
        return Response.success(equipmentBackup);
    }

    @Override
    @TaskAnnotation("getClassifyById")
    public Response getClassifyById(SessionFactory factory, String classifyid) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        return Response.success(mapper.serchClassifyById(classifyid));
    }

    @Override
    @TaskAnnotation("serch")
    public List<EquipmentBackup> serch(SessionFactory factory, EquipmentBackupQuery query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        List<EquipmentBackup> list;
        if (query.getBackApply() == null) {
            list = mapper.serch(query, 0);
        } else {
            int count = query.getBackApply().size();
            list = mapper.serch(query, count);
        }

        return list;
    }

    @Override
    @TaskAnnotation("serchnew")
    public List<EquipmentBackup> serchnew(SessionFactory factory, EquipmentBackupQuery query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        EquipmentMapper eqmapper = factory.getMapper(EquipmentMapper.class);

        Equipment eqbean = eqmapper.getById(query.getBackApply().get(0).getEquip_id(),null);
        int childrenQty = eqmapper.queryChildrenCount(eqbean.getFullPathCode());
        List<EquipmentBackup> list;
        if (childrenQty > 800) {
            OrderByInterceptor.setOrderBy(query.getOrders());
            PageHelper.startPage(query.getPage(), query.getPageSize());
            list = mapper.serch(query, 0);
        } else {
            List<Equipment> eqlist = eqmapper.queryChildrenByFullPathCode(eqbean.getFullPathCode());
            if (CollUtil.isEmpty(eqlist)) {
                return new ArrayList<>();
            }
            OrderByInterceptor.setOrderBy(query.getOrders());
            PageHelper.startPage(query.getPage(), query.getPageSize());
            for (OrderItem order : query.getOrders()) {
                order.setColumn(StrUtil.format("p.{}", order.getColumn()));
            }
            List<String> eqIds = eqlist.stream().map(Equipment::getId).collect(Collectors.toList());
            list = mapper.queryByEqIdIn(eqIds, query);
        }
        return list;
    }

    @Override
    @TaskAnnotation("add")
    public Response add(SessionFactory factory, EquipmentBackup query) {
        List<EquipmentApply> str = query.getBackApply();
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        Integer code = mapper.getByCode(query.getCode());
        if (code != 0) {
            return Response.fail("该编号已存在");
        } else {
            mapper.addnobind(query);
            str.forEach(list -> {
                list.setId(CodeTools.getCode32());
            });
            mapper.addbind(query.getId(), str);
            List<EquipmentBackup> equipmentBackup = mapper.getById(query.getId());
            return Response.success(equipmentBackup);
        }
    }


    @Override
    @TaskAnnotation("update")
    public Response update(SessionFactory factory, EquipmentBackup query) {
        List<EquipmentApply> str = query.getBackApply();
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        mapper.update(query, "0");
        mapper.delbind(query.getId());
        str.forEach(list -> {
            list.setId(CodeTools.getCode32());
        });
        mapper.addbind(query.getId(), str);
        return Response.success(mapper.getById(query.getId()));
    }

    @Override
    @TaskAnnotation("commit")
    public Response commit(SessionFactory factory, EquipmentBackup query) {
        List<EquipmentApply> str = query.getBackApply();
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        if (query.getId() == null || query.getId().equals("")) {           //新的表单提交
            Integer code = mapper.getByCode(query.getCode());
            if (code != 0) return Response.fail("该编号已存在");
            else {
                query.setId(CodeTools.getCode32());
                mapper.commitNew(query);
                str.forEach(list -> {
                    list.setId(CodeTools.getCode32());
                });
                mapper.addbind(query.getId(), str);
                List<EquipmentBackup> equipmentBackup = mapper.getById(query.getId());
                return Response.success(equipmentBackup);
            }
        } else {              //旧的表单更新
            mapper.commitOld(query);
            mapper.delbind(query.getId());
            str.forEach(list -> {
                list.setId(CodeTools.getCode32());
            });
            mapper.addbind(query.getId(), str);
            return Response.success(mapper.getById(query.getId()));
        }
    }

    @Override
    @TaskAnnotation("delete")
    public Response delete(SessionFactory factory, EquipmentBackup query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        String id = query.getId();
        String status = query.getStatus();
        if (status.equals("0")) {
            mapper.delById(id);
            mapper.delbind(id);
        } else if (status.equals("1")) {
            mapper.delByLogic(id);
        } else return Response.fail();
        return Response.success("删除成功");
    }


    @Override
    @TaskAnnotation("insertClassify")
    public Response insertClassify(SessionFactory factory, EamUser user, ClassifyBean classifyBean) {
        classifyBean.setId(CodeTools.getCode32());
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        mapper.insertClassify(classifyBean);
        return Response.success("添加成功");
    }

    @Override
    @TaskAnnotation("updateClassify")
    public Response updateClassify(SessionFactory factory, EamUser user, ClassifyBean classifyBean) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        mapper.updateClassify(classifyBean);
        return Response.success("修改成功");
    }

    @Override
    @TaskAnnotation("deleteClassify")
    public Response deleteClassify(SessionFactory factory, EamUser user, ClassifyBean classifyBean) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        mapper.deleteClassify(classifyBean);
        return Response.success("删除成功");
    }


    @Override
    @TaskAnnotation("getTree")
    public List<ClassifyBean> getTree(SessionFactory factory, ClassifyBean query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        List<EquipmentBackup> backups = mapper.serch(new EquipmentBackupQuery(), 0);
        mapper.resetBind();
        for (EquipmentBackup backup : backups) {
            if (backup.getIsBind().equals("0")) {
                mapper.setBind(backup.getClassifyId(), "1");
            }
        }
        List<ClassifyBean> list = mapper.getTree(query);
        list.forEach(list1 -> {
            list1.getChildren().forEach(list2 -> {
                list2.getChildren().sort(Comparator.comparing(ClassifyBean::getSort));
            });
            list1.getChildren().sort(Comparator.comparing(ClassifyBean::getSort));
        });
        list.sort(Comparator.comparing(ClassifyBean::getSort));

        if (!redisTemplate.hasKey("tree")){
            redisTemplate.opsForValue().set("tree", list, 1 * 60 * 60, TimeUnit.SECONDS);
        }

        return list;
    }

    @Override
    @TaskAnnotation("getTreeList")
    public List<ClassifyBean> getTreeList(SessionFactory factory) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        List<ClassifyBean> list = mapper.getTreeList();
        return list;
    }

    @Override
    @TaskAnnotation("importFile")
    public Response importFile(SessionFactory factory, List<EquipmentBackup> query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        checkCode(query, mapper);
        mapper.addlist(query);
        return Response.success("成功");
    }

    @Override
    public Response batchSaveEqBack(SessionFactory factory, List<EquipmentBackup> list) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        List<String> codelist = mapper.checkFile(list);
        if (CollUtil.isNotEmpty(codelist)) {
            String joinstr = codelist.stream().collect(Collectors.joining(","));
//            Assert.isFalse(true, "编号:" + joinstr + "系统已存在");
            return Response.fail(10002, StrUtil.format("编号：{}系统已存在", joinstr));
        }
        list.stream().forEach(eqb -> {
            eqb.setId(CodeTools.getCode32());
            eqb.setCreateTime(new Date());
            eqb.setCreateBy(getCurrUser().getName());
            eqb.setCreateBy(getCurrUser().getAccount());
            eqb.setDeleteFlag(0);
        });
        mapper.batchInsert(list);
        return Response.success("成功");
    }

    /**
     * 检查导入的数据中的编号是否有重复的
     *
     * @param query
     * @param mapper
     */
    public void checkCode(List<EquipmentBackup> query, EquipmentBackupMapper mapper) {
        List<String> list = mapper.checkFile(query);
        if (CollUtil.isNotEmpty(list)) {
            String joinstr = list.stream().collect(Collectors.joining(","));
            Assert.isFalse(true, "编号:" + joinstr + "系统已存在");
        }
    }

    @Override
    @TaskAnnotation("bindBatch")
    public Response bindBatch(SessionFactory factory, List<EquipmentBackup> query) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
        query.forEach(list -> {
            List<EquipmentApply> str = list.getBackApply();
            str.forEach(list2 -> {
                list2.setId(CodeTools.getCode32());
            });
            mapper.delbind(list.getId());
            mapper.addbind(list.getId(), str);
            mapper.update(list, "1");
        });
        return Response.success("成功");
    }

    @Override
    @TaskAnnotation("noBindBatch")
    public Response noBindBatch(SessionFactory factory, List<String> bingId) {
        EquipmentBackupMapper mapper = factory.getMapper(EquipmentBackupMapper.class);
            mapper.deleteByIdIn(bingId);
//            mapper.update(list, "1");
        return Response.success("成功");
    }
}
